home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / util / gnu / textutils_1_3.LHA / textutils-1.3 / src / wc.c < prev   
C/C++ Source or Header  |  1992-06-29  |  4KB  |  220 lines

  1. /* wc - print the number of bytes, words, and lines in files
  2.    Copyright (C) 1985, 1991 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Written by Paul Rubin, phr@ocf.berkeley.edu
  19.    and David MacKenzie, djm@gnu.ai.mit.edu. */
  20.  
  21. #include <stdio.h>
  22. #include <getopt.h>
  23. #include <sys/types.h>
  24. #include "system.h"
  25.  
  26. /* Size of atomic reads. */
  27. #define BUFFER_SIZE (16 * 1024)
  28.  
  29. void error ();
  30. void wc ();
  31. void wc_file ();
  32. void write_counts ();
  33.  
  34. /* Cumulative number of lines, words, and chars in all files so far. */
  35. unsigned long total_lines, total_words, total_chars;
  36.  
  37. /* Which counts to print. */
  38. int print_lines, print_words, print_chars;
  39.  
  40. /* Nonzero if we have ever read the standard input. */
  41. int have_read_stdin;
  42.  
  43. /* The name this program was run with. */
  44. char *program_name;
  45.  
  46. /* The error code to return to the system. */
  47. int exit_status;
  48.  
  49. struct option longopts[] =
  50. {
  51.   {"bytes", 0, NULL, 'c'},
  52.   {"chars", 0, NULL, 'c'},
  53.   {"lines", 0, NULL, 'l'},
  54.   {"words", 0, NULL, 'w'},
  55.   {NULL, 0, NULL, 0}
  56. };
  57.  
  58. void
  59. main (argc, argv)
  60.      int argc;
  61.      char **argv;
  62. {
  63.   int optc;
  64.   int nfiles;
  65.  
  66.   program_name = argv[0];
  67.   exit_status = 0;
  68.   print_lines = print_words = print_chars = 0;
  69.   total_lines = total_words = total_chars = 0;
  70.  
  71.   while ((optc = getopt_long (argc, argv, "clw", longopts, (int *) 0)) != EOF)
  72.     switch (optc)
  73.       {
  74.       case 'c':
  75.     print_chars = 1;
  76.     break;
  77.  
  78.       case 'l':
  79.     print_lines = 1;
  80.     break;
  81.  
  82.       case 'w':
  83.     print_words = 1;
  84.     break;
  85.  
  86.       default:
  87.     fprintf (stderr, "\
  88. Usage: %s [-clw] [--bytes] [--chars] [--lines] [--words] [file...]\n", argv[0]);
  89.     exit (1);
  90.       }
  91.  
  92.   if (print_lines + print_words + print_chars == 0)
  93.     print_lines = print_words = print_chars = 1;
  94.  
  95.   nfiles = argc - optind;
  96.  
  97.   if (nfiles == 0)
  98.     {
  99.       have_read_stdin = 1;
  100.       wc (0, "");
  101.     }
  102.   else
  103.     {
  104.       for (; optind < argc; ++optind)
  105.     wc_file (argv[optind]);
  106.  
  107.       if (nfiles > 1)
  108.     write_counts (total_lines, total_words, total_chars, "total");
  109.     }
  110.   
  111.   if (have_read_stdin && close (0))
  112.     error (1, errno, "-");
  113.  
  114.   exit (exit_status);
  115. }
  116.  
  117. void
  118. wc_file (file)
  119.      char *file;
  120. {
  121.   if (!strcmp (file, "-"))
  122.     {
  123.       have_read_stdin = 1;
  124.       wc (0, file);
  125.     }
  126.   else
  127.     {
  128.       int fd = open (file, O_RDONLY);
  129.       if (fd == -1)
  130.     {
  131.       error (0, errno, "%s", file);
  132.       exit_status = 1;
  133.       return;
  134.     }
  135.       wc (fd, file);
  136.       if (close (fd))
  137.     {
  138.       error (0, errno, "%s", file);
  139.       exit_status = 1;
  140.     }
  141.     }
  142. }
  143.  
  144. void
  145. wc (fd, file)
  146.      int fd;
  147.      char *file;
  148. {
  149.   char buf[BUFFER_SIZE];
  150.   register int bytes_read;
  151.   register int in_word = 0;
  152.   register unsigned long lines, words, chars;
  153.   
  154.   lines = words = chars = 0;
  155.   
  156.   while ((bytes_read = read (fd, buf, BUFFER_SIZE)) > 0)
  157.     {
  158.       register char *p = buf;
  159.       do
  160.     {
  161.       chars++;
  162.       switch (*p++)
  163.         {
  164.         case '\n':
  165.           lines++;
  166.           /* Fall through. */
  167.         case '\r':
  168.         case '\f':
  169.         case '\t':
  170.         case '\v':
  171.         case ' ':
  172.           if (in_word)
  173.         {
  174.           in_word = 0;
  175.           words++;
  176.         }
  177.           break;
  178.         default:
  179.           in_word = 1;
  180.           break;
  181.         }
  182.     } while (--bytes_read);
  183.     }
  184.   if (bytes_read < 0)
  185.     {
  186.       error (0, errno, "%s", file);
  187.       exit_status = 1;
  188.     }
  189.   if (in_word)
  190.     words++;
  191.   write_counts (lines, words, chars, file);
  192.   total_lines += lines;
  193.   total_words += words;
  194.   total_chars += chars;
  195. }
  196.  
  197. void
  198. write_counts (lc, wc, cc, file)
  199.      unsigned long lc, wc, cc;
  200.      char *file;
  201. {
  202.   if (print_lines)
  203.     printf ("%7lu", lc);
  204.   if (print_words)
  205.     {
  206.       if (print_lines)
  207.     putchar (' ');
  208.       printf ("%7lu", wc);
  209.     }
  210.   if (print_chars)
  211.     {
  212.       if (print_lines || print_words)
  213.     putchar (' ');
  214.       printf ("%7lu", cc);
  215.     }
  216.   if (*file)
  217.     printf (" %s", file);
  218.   putchar ('\n');
  219. }
  220.